﻿using System;
using AutoMapper;
using Enferno.Public.InversionOfControl;
using Enferno.Public.Web.Builders;
using Enferno.Public.Web.Mappers.ProductProfiles;
using Enferno.Public.Web.Repositories;
using Enferno.StormApiClient.ExposeProxy;
using Enferno.StormApiClient.Products;
using Enferno.Web.StormUtils;
using Microsoft.Practices.Unity;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Rhino.Mocks;
using ParametricValue = Enferno.StormApiClient.Products.ParametricValue;

namespace Enferno.Public.Web.Test.Builders
{
    [TestClass]
    public class ProductListBuilderTests
    {
        [TestInitialize]
        public void Initialize()
        {
            var rules = MockRepository.GenerateMock<ISiteRules>();
            IoC.RegisterInstance(typeof(ISiteRules), rules);
            Mapper.AddProfile<ProductProfile>();
        }

        [TestMethod]
        public void BuildProductListWithNullList()
        {
            // Arrange
            var rules = MockRepository.GenerateMock<ISiteRules>();

            // Act
            var productBuilder = new ProductListBuilder(rules);
            var result = productBuilder.BuildProductList(null);

            // Assert
            Assert.AreEqual(null, result);
        }

        [TestMethod]
        public void BuildProductListWithEmptyList()
        {
            // Arrange
            var rules = MockRepository.GenerateMock<ISiteRules>();
            var productList = new ProductItemPagedList
            {
                Items = new ProductItemList()
            };

            // Act
            var productBuilder = new ProductListBuilder(rules);
            var result = productBuilder.BuildProductList(productList);

            // Assert
            Assert.AreNotEqual(null, result);
        }

        [TestMethod]
        public void BuildProductList03()
        {
            // Arrange
            var rules = MockRepository.GenerateMock<ISiteRules>();
            var productList = new ProductItemPagedList
            {
                ItemCount =  1,
                Items = new ProductItemList
                {
                    new ProductItem
                    {
                        Manufacturer = new ProductManufacturer{Id = 1, Name = "MockManufacturer" }
                    }
                }
            };

            var stormContext = MockRepository.GenerateMock<IStormContext>();
            stormContext.Stub(x => x.Configuration).Return(new StormConfigurationSection());
            stormContext.Stub(x => x.ShowPricesIncVat).Return(false);
            StormContext.SetInstance(stormContext);

            // Act
            var productBuilder = new ProductListBuilder(rules);
            var result = productBuilder.BuildProductList(productList);

            // Assert
            Assert.AreEqual(0, result.Filters.Count);
            Assert.AreEqual(1, result.ItemCount);
            Assert.AreEqual("MockManufacturer", result.Items[0].Manufacturer.Name);
        }

        [TestMethod]
        public void BuildProductList04()
        {
            // Arrange
            var rules = MockRepository.GenerateMock<ISiteRules>();
            var productList = new ProductItemPagedList
            {
                Items = new ProductItemList
                {
                    new ProductItem
                    {
                        Id = 22,
                        Name = "Bananahammock",
                        CategoryId = 25,
                        Manufacturer = new ProductManufacturer{Id = 1, Name = "MockManufacturer" },
                        AdditionalImageKeySeed = "14:" + Guid.Empty,
                        FlagIdSeed = "1,3,5",
                        VariantParametricSeed = "112",
                        ParametricListSeed = "111:10,111:12,111:14",
                        ParametricMultipleSeed = "112:20,112:22,112:24",
                        ParametricValueSeed = "113:30,113:32,113:34"
                    }
                },
                ItemCount = 1
            };

            var stormContext = MockRepository.GenerateMock<IStormContext>();
            stormContext.Stub(x => x.Configuration).Return(new StormConfigurationSection());
            stormContext.Stub(x => x.ShowPricesIncVat).Return(false);
            stormContext.Stub(x => x.CultureCode).Return("sv");
            StormContext.SetInstance(stormContext);

            var productsRepository = MockRepository.GenerateMock<IProductRepository>();
            productsRepository.Stub(x => x.ListParametricInfo()).IgnoreArguments()
                .Return(
                new ParametricInfoList
                {
                    new ParametricInfo {Id = 111, Type = ParametricType.ListValue, ValueType = ParametricValueType.Integer},
                    new ParametricInfo { Id = 112, Type = ParametricType.MultiValue, ValueType = ParametricValueType.Decimal },
                    new ParametricInfo { Id = 113, Type = ParametricType.Value, ValueType = ParametricValueType.Text },
                }
            );

            productsRepository.Stub(x => x.ListParametricValues()).IgnoreArguments()
                .Return(
                new ParametricValueList
                {
                    new ParametricValue { Id = 10, Name = "Valuee", Description = "Desc", Code = "Coode", SortOrder = 1, Type = ParametricType.ListValue.ToString() },
                    new ParametricValue { Id = 12, Name = "Valuee", Description = "Desc", Code = "Coode", SortOrder = 1, Type = ParametricType.ListValue.ToString() },
                    new ParametricValue { Id = 14, Name = "Valuee", Description = "Desc", Code = "Coode", SortOrder = 1, Type = ParametricType.ListValue.ToString() },
                    new ParametricValue { Id = 20, Name = "Valuee", Description = "Desc", Code = "Coode", SortOrder = 1, Type = ParametricType.MultiValue.ToString() },
                    new ParametricValue { Id = 22, Name = "Valuee", Description = "Desc", Code = "Coode", SortOrder = 1, Type = ParametricType.MultiValue.ToString() },
                    new ParametricValue { Id = 24, Name = "Valuee", Description = "Desc", Code = "Coode", SortOrder = 1, Type = ParametricType.MultiValue.ToString() },
                    new ParametricValue { Id = 30, Name = "Valuee", Description = "Desc", Code = "Coode", SortOrder = 1, Type = ParametricType.Value.ToString() },
                    new ParametricValue { Id = 32, Name = "Valuee", Description = "Desc", Code = "Coode", SortOrder = 1, Type = ParametricType.Value.ToString() },
                    new ParametricValue { Id = 34, Name = "Valuee", Description = "Desc", Code = "Coode", SortOrder = 1, Type = ParametricType.Value.ToString() },
                }
            );
   
            var repository = MockRepository.GenerateMock<IRepository>();
            repository.Stub(x => x.Products).Return(productsRepository);

            IoC.Container.RegisterInstance(typeof(IRepository), repository, new PerThreadLifetimeManager());
            ApplicationDictionary.Instance.Refresh();

            // Act
            var productBuilder = new ProductListBuilder(rules);
            var result = productBuilder.BuildProductList(productList);

            // Assert
            Assert.AreNotEqual(null, result);
            Assert.AreEqual(1, result.ItemCount);
            Assert.AreEqual(1, result.Items.Count);
            Assert.AreEqual("MockManufacturer", result.Items[0].Manufacturer.Name);
            Assert.AreEqual(2, result.Items[0].Files.Count, "Files");
            Assert.AreEqual("Bananahammock", result.Items[0].Files[0].AltText); 
            Assert.AreEqual(3, result.Items[0].Flags.Count);
            Assert.AreEqual(5, result.Items[0].Flags[2]);
            Assert.AreEqual(2, result.Items[0].Parametrics.Count, "Parametrics");
            Assert.AreEqual(111, result.Items[0].Parametrics[0].Id);
            Assert.AreEqual(3, result.Items[0].Parametrics[0].Values.Count);
            Assert.AreEqual("Valuee", result.Items[0].Parametrics[0].Values[0].Name);
        }
    }
}

